'use client';
import { AudioOutlined, SoundOutlined } from '@ant-design/icons';
import { Bubble, Prompts, Sender, Welcome, useXAgent, useXChat } from '@ant-design/x';
import type { BubbleDataType } from '@ant-design/x/es/bubble/BubbleList';
import { Button, Flex, Space, Spin, message, Image, Typography, Avatar } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { marked } from 'marked';
import { useStyle } from './styles';
import VoiceAnimationIcon from '../components/VoiceAnimationIcon/index';
import StreamSpeech from '../components/StreamSpeech';
import { debounce } from 'lodash';

const Independent: React.FC = () => {
	const { styles } = useStyle();
	const abortController = useRef<AbortController>(null);
	const audioRef = useRef<HTMLAudioElement | null>(null);
	const [inputValue, setInputValue] = useState('');
	// 使用message.useMessage钩子创建上下文相关的消息API和上下文持有者
	const [messageApi, contextHolder] = message.useMessage();
	// 语音输入状态
	const [isListening, setIsListening] = useState(false);
	const recognitionRef = useRef<any>(null);
	const [transcript, setTranscript] = useState('');
	// 开始状态
	const [isStart, setIsStart] = useState(false);

	// 1. 简化状态
	const [currentText, setCurrentText] = useState(""); // 当前正在处理的文本
	const [isProcessing, setIsProcessing] = useState(false); // 是否正在处理中
	const pendingTextRef = useRef<string>(""); // 累积缓冲区
	const textQueueRef = useRef<string[]>([]); // 文本队列，使用ref避免状态更新问题
	// 跟踪当前正在播放的音频元素
	const currentAudioRef = useRef<HTMLAudioElement | null>(null);
	// 添加全局锁，避免重复处理
	const isProcessingLockRef = useRef<boolean>(false);

	// 添加预加载的音频缓存
	const preloadedBlobsRef = useRef<{[key: string]: Blob}>({});

	// 2. 严格同步的处理和播放函数
	const processNextText = () => {
		// 检查全局锁 - 这是关键!
		if (isProcessingLockRef.current) {
			console.log('全局锁已锁定，跳过重复处理');
			return;
		}
		
		// 如果正在处理或队列为空，不做任何事
		if (isProcessing || textQueueRef.current.length === 0) {
			console.log('跳过处理: 正在处理=', isProcessing, '队列长度=', textQueueRef.current.length);
			return;
		}
		
		// 设置全局锁
		isProcessingLockRef.current = true;
		console.log('进入处理，全局锁已锁定');
		
		// 取出队列中第一个文本
		const text = textQueueRef.current.shift() || "";
		console.log(`开始处理文本: "${text}"`);
		
		// 设置处理状态
		setIsProcessing(true);
		setCurrentText(text);
		
		// 同步函数，确保一个步骤完成后再进行下一步
		const synthesizeAndPlay = async () => {
			try {
				// 如果当前已有音频在播放，先停止它
				if (currentAudioRef.current) {
					console.log('强制停止当前正在播放的音频');
					currentAudioRef.current.pause();
					currentAudioRef.current = null;
				}
				
				console.log('开始合成...');
				
				// 检查是否有预加载的音频
				let audioBlob: Blob | null = null;
				if (preloadedBlobsRef.current[text]) {
					audioBlob = preloadedBlobsRef.current[text];
					console.log(`使用预加载的音频: ${audioBlob.size} 字节`);
					// 使用后清除缓存
					delete preloadedBlobsRef.current[text];
				} else {
					// 1. 合成阶段 - 等待API响应
					const response = await fetch('https://teacher.dianchuang.club/api/synthesize', {
						method: 'POST',
						headers: { 'Content-Type': 'application/json' },
						body: JSON.stringify({ 
							text,
							voice_type: "1001",
							sample_rate: 16000
						}),
					});
					
					if (!response.ok) {
						throw new Error(`合成请求失败: ${response.status}`);
					}
					
					audioBlob = await response.blob();
					console.log(`合成成功: ${audioBlob.size} 字节`);
				}
				
				// 检查是否仍然处于锁定状态 (防止用户点击了中断)
				if (!isProcessingLockRef.current) {
					console.log('处理被中断，不再继续播放');
					return;
				}
				
				// 2. 播放阶段 - 创建音频并播放
				const url = URL.createObjectURL(audioBlob);
				const audio = new Audio(url);
				
				// 等待音频元数据加载完成，以获取时长
				await new Promise<void>((loadResolve) => {
					audio.onloadedmetadata = () => {
						const duration = audio.duration;
						const charCount = text.length;
						const avgTimePerChar = (duration / charCount).toFixed(3);
						console.log(`音频加载完成，时长: ${duration.toFixed(2)}秒，文本长度: ${charCount}字符，平均每字时长: ${avgTimePerChar}秒`);
						loadResolve();
						
						// 如果音频时长大于3秒，在还剩2秒时提前处理下一句
						if (duration > 3 && textQueueRef.current.length > 0) {
							const preloadTime = Math.max(duration - 2, 0) * 1000; // 提前2秒，但不小于0
							console.log(`将在${preloadTime}毫秒后(音频播放到最后2秒时)预处理下一句`);
							
							setTimeout(() => {
								// 在处理下一句之前检查当前音频是否仍在播放
								if (currentAudioRef.current === audio && !isProcessingLockRef.current && textQueueRef.current.length > 0) {
									console.log('提前开始处理下一句...');
									// 创建一个临时锁，避免在播放完成回调中再次处理
									isProcessingLockRef.current = true;
									processNextText();
								}
							}, preloadTime);
						}
					};
				});
				
				// 保存当前音频引用
				currentAudioRef.current = audio;
				
				// 3. 使用Promise包装音频播放完成事件
				await new Promise((resolve, reject) => {
					// 设置超时，防止音频播放卡住
					const timeoutId = setTimeout(() => {
						console.log('音频播放超时，强制继续');
						resolve(true);
					}, 30000); // 最多30秒
					
					// 添加提前预处理功能：在音频还有2秒结束时开始处理下一句
					if (audio.duration > 3 && textQueueRef.current.length > 0) {
						const preloadTime = Math.max((audio.duration - 2) * 1000, 0); // 提前2秒，但不小于0
						console.log(`音频时长${audio.duration.toFixed(2)}秒，将在${preloadTime.toFixed(0)}毫秒后(还剩约2秒时)预处理下一句`);
						
						const preloadTimeoutId = setTimeout(() => {
							// 检查是否仍在播放当前音频
							if (currentAudioRef.current === audio && textQueueRef.current.length > 0) {
								console.log('提前预处理下一句...');
								// 我们不释放当前的锁，而是启动一个后台的预处理
								// 创建克隆队列的副本进行处理，避免干扰主队列
								const nextText = textQueueRef.current[0];
								if (nextText) {
									console.log(`开始预加载下一句: "${nextText}"`);
									// 开始预处理API请求，无需等待结果
									fetch('https://teacher.dianchuang.club/api/synthesize', {
										method: 'POST',
										headers: { 'Content-Type': 'application/json' },
										body: JSON.stringify({ 
											text: nextText,
											voice_type: "1001",
											sample_rate: 16000
										}),
									})
									.then(response => {
										if (!response.ok) {
											console.error('预处理合成请求失败:', response.status);
											return null;
										}
										return response.blob();
									})
									.then(blob => {
										if (blob) {
											console.log(`预处理合成成功: ${blob.size} 字节，等待当前音频播放完毕后使用`);
											// 存储预处理的结果，以便后续使用
											preloadedBlobsRef.current[nextText] = blob;
										}
									})
									.catch(err => {
										console.error('预处理请求出错:', err);
									});
								}
							}
						}, preloadTime);
						
						// 确保在音频完成或错误时清除预加载定时器
						audio.addEventListener('ended', () => clearTimeout(preloadTimeoutId));
						audio.addEventListener('error', () => clearTimeout(preloadTimeoutId));
					}
					
					audio.onended = () => {
						console.log('音频播放完毕');
						clearTimeout(timeoutId);
						resolve(true);
					};
					
					audio.onerror = (e) => {
						console.error('播放出错:', e);
						clearTimeout(timeoutId);
						reject(new Error('音频播放失败'));
					};
					
					// 开始播放
					audio.play().catch(err => {
						console.error('播放失败:', err);
						clearTimeout(timeoutId);
						reject(err);
					});
				});
				
				// 4. 播放完成后清理资源
				URL.revokeObjectURL(url);
				currentAudioRef.current = null;
				
			} catch (error) {
				console.error('处理过程出错:', error);
			} finally {
				// 5. 无论成功失败，都重置状态并处理下一个
				console.log('处理完成，准备下一项');
				setIsProcessing(false);
				setCurrentText("");
				currentAudioRef.current = null;
				
				// 重要: 释放全局锁
				isProcessingLockRef.current = false;
				console.log('全局锁已释放');
				
				// 延迟一点再处理下一个，确保UI状态已更新
				setTimeout(() => {
					if (textQueueRef.current.length > 0) {
						console.log(`队列中还有${textQueueRef.current.length}项待处理`);
						processNextText();
					} else {
						console.log('队列已清空');
					}
				}, 150);
			}
		};
		
		// 启动同步处理流程
		synthesizeAndPlay();
	};

	// 3. 添加句子到队列
	const addToQueue = (sentence: string) => {
		if (sentence && sentence.length >= 3) {
			textQueueRef.current.push(sentence);
			console.log(`添加句子到队列: ${sentence}, 当前队列长度: ${textQueueRef.current.length}`);
			
			// 如果当前没有处理中的文本且全局锁未锁定，才开始处理
			if (!isProcessing && !isProcessingLockRef.current) {
				processNextText();
			}
		}
	};

	// 4. 修改transformMessage简化逻辑
	useEffect(() => {
		// 配置 marked 选项
		marked.setOptions({
			breaks: true, // 将换行符转换为 <br>
			gfm: true, // 使用 GitHub 风格的 Markdown
		});
	}, []);

	// ==================== Runtime ====================
	const [agent] = useXAgent<BubbleDataType>({
		baseURL: 'https://teacher.dianchuang.club/api/chat/completions',
	});
	const loading = agent.isRequesting();

	const { onRequest, messages, setMessages } = useXChat({
		agent,
		// 请求失败时的回调处理
		requestFallback: (_, { error }) => {
			if (error.name === 'AbortError') {
				return {
					content: '请求被中断',
					role: 'assistant',
				};
			}
			return {
				content: '请求失败，请重试！',
				role: 'assistant',
			};
		},
		// 自定义消息转换：处理特定格式的响应数据
		transformMessage: (info) => {
			const { originMessage, chunk } = info || {};
			let currentText = '';
			try {
				if (chunk?.data && !chunk?.data.includes('DONE')) {
					const message = JSON.parse(chunk?.data);
					currentText = !message?.choices?.[0].delta?.content ? '' : message?.choices?.[0].delta?.content;
					
					// 累积文本
					if (currentText) {
						pendingTextRef.current += currentText;
						
						// 句子结束时处理
						if (currentText.match(/[.。!！?？;；]/)) {
							const sentence = extractLastSentence(pendingTextRef.current);
							console.log(`提取句子: ${sentence}`);
							addToQueue(sentence);
							pendingTextRef.current = '';
						}
					}
				}
			} catch (error) {
				console.error('处理消息出错:', error);
			}
			return {
				content: (originMessage?.content || '') + currentText,
				role: 'assistant',
			};
		},
		resolveAbortController: (controller) => {
			abortController.current = controller;
		},
	});

	// 提取最后一个完整句子的辅助函数
	const extractLastSentence = (text: string): string => {
		// 按标点符号分割文本
		const sentences = text.split(/([.。!！?？;；])/);
		if (sentences.length <= 1) return '';
		
		// 合并最后一个句子和标点
		let lastIndex = sentences.length - 1;
		// 如果最后一个是标点，取前一个
		if (sentences[lastIndex].match(/^[.。!！?？;；]$/)) {
			lastIndex -= 1;
		}
		// 找到最后一个非空句子
		while (lastIndex >= 0 && !sentences[lastIndex].trim()) {
			lastIndex -= 2;
		}
		if (lastIndex < 0) return '';
		
		// 返回句子+标点
		const sentence = sentences[lastIndex];
		const punctuation = lastIndex + 1 < sentences.length ? sentences[lastIndex + 1] : '';
		return sentence + punctuation;
	};

	// ==================== Event ====================
	const onSubmit = (val: string) => {
		if (!val) return;

		if (loading) {
			messageApi.error('请求正在进行中，请等待请求完成。');
			return;
		}

		onRequest({
			stream: true,
			message: { role: 'user', content: val },
		});

		// 提交后清空临时记录的识别文本
		setTranscript('');
	};

	// 处理语音按钮点击
	const handleVoiceButtonClick = () => {
		console.log('语音按钮点击，当前状态:', isListening ? '正在录音' : '未录音');
		setIsListening(!isListening);
		if (isListening) {
			// 停止录音时，如果有内容则自动提交
			if (transcript.trim()) {
				console.log('停止录音，自动提交识别内容:', transcript);
				onSubmit(transcript);
			} else {
				console.log('停止录音，无识别内容');
			}
		} else {
			// 开始新的录音时，清空之前的结果
			console.log('开始新录音，清空之前结果');
			setTranscript('');
		}
	};

	const renderMarkdown = (content: string) => {
		if (!content) return '';
		try {
			// 使用 marked 渲染 markdown
			const rendered = marked(content);
			return (
				<Typography>
					<div dangerouslySetInnerHTML={{ __html: rendered }} />
				</Typography>
			);
		} catch (error) {
			console.error('渲染 markdown 失败:', error);
			// 出错时直接返回原始内容
			return <Typography>{content}</Typography>;
		}
	};

	const startChat = () => {
		setIsStart(true);
		// 设置一个初始的欢迎消息
		// 发送语音合成请求
		fetch('https://teacher.dianchuang.club/api/synthesize', {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: JSON.stringify({
				text: '同学们好。欢迎大家来到我们的数学课堂，我是你们的金智老师，今天我给大家带来一组图片。漂亮吗？',
			}),
		})
			.then((response) => response.blob())
			.then((blob) => {
				// 创建URL对象
				const audioUrl = URL.createObjectURL(blob);

				// 创建audio元素并保存引用
				if (!audioRef.current) {
					audioRef.current = new Audio(audioUrl);

					// 在音频播放完后释放URL对象
					audioRef.current.onended = () => {
						URL.revokeObjectURL(audioUrl);
					};
				} else {
					// 如果已经存在，更新URL
					URL.revokeObjectURL(audioRef.current.src);
					audioRef.current.src = audioUrl;
				}

				// 直接播放音频
				audioRef.current
					.play()
					.then(() => console.log('语音合成播放成功'))
					.catch((error) => console.error('播放音频失败:', error));

				console.log('语音合成成功，正在播放');
			})
			.catch((error) => console.error('语音合成请求失败:', error));

		setMessages([
			{
				message: {
					role: 'assistant',
					content:
						'同学们好。欢迎大家来到我们的数学课堂，我是你们的金智老师，今天我给大家带来一组图片。漂亮吗？<div style="display:flex; flex-wrap:wrap; gap:10px; justify-content:center; margin:10px 0;"><img src="/math-image.png" alt="数学图片1" style="max-width:30%; border-radius:8px;" /><img src="/math-image2.png" alt="数学图片2" style="max-width:30%; border-radius:8px;" /><img src="/math-image3.png" alt="数学图片3" style="max-width:30%; border-radius:8px;" /></div>',
				},
				status: 'success',
				id: '',
			},
		]);

		setTimeout(handleVoiceButtonClick, 10000);
	};

	const chatRender = (
		<div className={styles.chatRender}>
			<Space
				direction="vertical"
				size={16}
				style={{
					paddingInline: 'calc(calc(100% - 700px) /2)',
					height: '100%',
					alignItems: 'center',
          justifyContent: !isStart ? 'center' : 'flex-start',
					display: 'flex',
				}}
				className={styles.placeholder}
			>
				<Flex align="center" justify="space-between" style={{ width: '100%' }}>
					<div
						style={{
							display: 'flex',
							alignItems: 'start',
							justifyContent: 'center',
							borderRadius: isStart ? 99999 : 0,
							overflow: 'hidden',
							width: isStart ? '25vh' : 800,
							height: isStart ? '25vh' : '100%',
							transition: 'all 0.5s ease',
						}}
					>
						<Image
							preview={false}
							src="/teacher.png"
							style={{
								width: '100%',
								height: '100%',
								objectFit: 'cover',
								transition: 'all 0.5s ease',
							}}
						/>
					</div>

					{!isStart && (
						<div style={{ marginLeft: 20, maxWidth: 400 }}>
							<Typography.Title level={3}>金智老师</Typography.Title>
							<Typography.Paragraph>
								资深数学教育专家，拥有20年教学经验。专注于启发式教学，
								善于运用生动形象的例子帮助学生理解抽象概念，让数学学习变得轻松有趣。
							</Typography.Paragraph>
							<Button type="primary" size="large" onClick={startChat}>
								开始上课
							</Button>
						</div>
					)}
				</Flex>

				{
					/* 🌟 只显示assistant的最后一条消息 */
					(() => {
						// 筛选出所有assistant消息
						const assistantMessages = messages?.filter((i) => i.message.role === 'assistant') || [];
						// 获取最后一条assistant消息
						const lastAssistantMessage =
							assistantMessages.length > 0 ? assistantMessages[assistantMessages.length - 1] : null;

						if (!lastAssistantMessage) {
							return null;
						}

						return (
							<Bubble
								content={lastAssistantMessage.message.content}
								classNames={{
									content: lastAssistantMessage.status === 'loading' ? styles.loadingMessage : '',
								}}
								typing={
									lastAssistantMessage.status === 'loading' ? { step: 5, interval: 20 } : false
								}
								messageRender={renderMarkdown}
							/>
						);
					})()
				}
				{/* 显示语音识别结果 */}
				{/* {isListening && transcript && (
					<div
						style={{
							marginTop: '10px',
							padding: '10px',
							backgroundColor: 'rgba(255, 255, 255, 0.8)',
							borderRadius: '8px',
							maxWidth: '80%',
						}}
					>
						<Typography.Text type="secondary">正在识别: {transcript}</Typography.Text>
					</div>
				)} */}
			</Space>
		</div>
	);

	const chatSender = (
		<>
			{/* 🌟 输入框 */}
			<Sender
				value={inputValue}
				// header={senderHeader}
				onSubmit={() => {
					onSubmit(inputValue);
					setInputValue('');
				}}
				onChange={setInputValue}
				onCancel={() => {
					abortController.current?.abort();
				}}
				loading={loading}
				className={styles.sender}
				allowSpeech
				actions={(_, info) => {
					const { SendButton, LoadingButton, SpeechButton } = info.components;
					return (
						<Flex gap={4}>
							<SpeechButton className={styles.speechButton} />
							{loading ? <LoadingButton type="default" /> : <SendButton type="primary" />}
						</Flex>
					);
				}}
				placeholder="在这里输入你的问题"
			/>
		</>
	);

	const chatSenderSpeech = (
		<div style={{ display: 'flex', justifyContent: 'center' }}>
			<Button
				type="primary"
				shape="circle"
				icon={
					isListening ? (
						<VoiceAnimationIcon style={{ fontSize: '24px' }} />
					) : (
						<AudioOutlined style={{ fontSize: '24px' }} />
					)
				}
				style={{ width: '70px', height: '70px' }}
				onClick={handleVoiceButtonClick}
			/>
		</div>
	);

	// 语音控制按钮
	const VoiceControlButton = () => (
		<Button
			type="text"
			icon={isProcessing ? <SoundOutlined /> : <SoundOutlined style={{ color: '#bbb' }} />}
			onClick={() => {
				// 如果当前有音频播放，停止它
				if (currentAudioRef.current) {
					currentAudioRef.current.pause();
					currentAudioRef.current = null;
				}
				// 重置状态
				setIsProcessing(false);
				isProcessingLockRef.current = false;
				setCurrentText("");
				console.log('音频播放已手动停止');
			}}
			style={{ position: 'absolute', top: 10, right: 10 }}
		/>
	);

	// ==================== Render ==================
  
	return (
		<div className={styles.layout}>
			{/* 渲染消息上下文持有者 */}
			{contextHolder}
			
			{/* 语音控制按钮 */}
			{/* <VoiceControlButton />			 */}
			
			{/* 其他UI元素 */}
			<div className={styles.chat}>
				{chatRender}
				{isStart && chatSenderSpeech}
				{/* {chatSender} */}
			</div>
		</div>
	);
};

export default Independent;
